require "Common/define"
require "Logic/Config"
require "Common/functions"
---@class HeroManorManager
HeroManorManager = HeroManorManager or {};
local this = HeroManorManager;

function HeroManorManager.init()
    this.heroManorTab = nil;
    this.manorInfo = {};
    this.manorMaster = {};
    this.highQuality = false;
    local saveData = GetPlayerPrefs("ManorManager"..logicMgr.HeroManager.GetRoleInfo().playerId);
    if saveData == nil or tonumber(saveData) == 1 then
        this.highQuality = true;
    end
end

function HeroManorManager.OnDestroy()
    this.heroManorTab = nil;
    this.manorInfo = nil;
    this.manorMaster = nil;
end

function HeroManorManager.getCityModelData(id)
    if id == nil then
        return dataTable.getDataTable("t_heromanorcitymodel");
    end
    return dataTable.getDataTableByStringId("t_heromanorcitymodel", id);
end

function HeroManorManager.getHeroManorData(heroId, star, isList)
    star = star or 20;
    if this.heroManorTab == nil then
        this.heroManorTab = {};
        local cfg = dataTable.getDataTable("t_heromanor");
        for k, v in pairs(cfg) do
            local lType = tostring(v.f_HeroId);
            if this.heroManorTab[lType] == nil then
                this.heroManorTab[lType] = {};
            end
            table.insert(this.heroManorTab[lType], v);
        end
        for k, v in pairs(this.heroManorTab) do
            table.sort(v, function(a, b)
                return a.f_HeroStar < b.f_HeroStar;
            end)
        end
    end
    local data = this.heroManorTab[tostring(heroId)];
    if data == nil then
        return nil;
    end
    if isList ~= nil and isList then
        return data;
    end
    local item = nil;
    for k, v in pairs(data) do
        if star >= v.f_HeroStar then
            item = v;
        else
            break;
        end
    end
    return item;
end

function HeroManorManager.setManorInfo(id, data)
    this.manorInfo = this.manorInfo or {}
    local items = {};
    this.manorMaster = {};
    for k, v in pairs(data) do
        local lc = {};
        lc.masterId = tostring(v.masterId);
        local visitors = {};
        for lk, lv in pairs(v.visitors) do
            table.insert(visitors, tostring(lv));
        end
        this.manorMaster[lc.masterId] = visitors;
        items[tostring(v.id)] = lc;
    end
    this.manorInfo[tostring(id)] = items;
end

function HeroManorManager.getAllManorInfo()
    return this.manorInfo;
end

function HeroManorManager.getManorInfo(id, index)
    id = id or 1;
    if this.manorInfo[tostring(id)] == nil then
        return nil;
    end
    if index == nil then
        return this.manorInfo[tostring(id)];
    end
    return this.manorInfo[tostring(id)][tostring(index)];
end

function HeroManorManager.getMasterCityIdAndIndex(partnerId)
    if this.isManorMaster(partnerId) then
        partnerId = tostring(partnerId);
        for k, v in pairs(this.manorInfo) do
            for lk, lv in pairs(v) do
                if lv.masterId ~= nil and lv.masterId == partnerId then
                    return k, lk;
                end
            end
        end
    end
    return nil, nil;
end

function HeroManorManager.getManorVisitors(partnerId)
    return this.manorMaster[tostring(partnerId)];
end

function HeroManorManager.isManorMaster(partnerId)
    if this.manorMaster[tostring(partnerId)] ~= nil then
        return true;
    end
    return false;
end

function HeroManorManager.isManorGuest(partnerId)
    partnerId = tostring(partnerId);
    for k, v in pairs(this.manorMaster) do
        for ik, iv in pairs(v) do
            if partnerId == iv then
                return true;
            end
        end
    end
    return false;
end

function HeroManorManager.isGuestByManor(partnerId, guestId)
    local guest = this.manorMaster[tostring(partnerId)];
    if guest ~= nil then
        for ik, iv in pairs(guest) do
            if guestId == iv then
                return true;
            end
        end
    end
    return false;
end

function HeroManorManager.getManorMasterByGuest(partnerId)
    partnerId = tostring(partnerId);
    for k, v in pairs(this.manorMaster) do
        for ik, iv in pairs(v) do
            if partnerId == iv then
                return tonumber(k);
            end
        end
    end
    return 0;
end

function HeroManorManager.getAllAttrByMaster(partnerId)
    return this.getAllAttrByGuest(this.getManorVisitors(partnerId), partnerId);
end

function HeroManorManager.getAllAttrByGuest(visitors, partnerId)
    if visitors == nil then
        return nil;
    end
    local heroInfo = logicMgr.HeroManager.getHeroDatabyPartnerId(partnerId, true);
    if heroInfo == nil then
        return nil;
    end
    local cityInd, index = this.getMasterCityIdAndIndex(partnerId);
    local modelData = this.getCityModelData(index);
    local heroStar = 100;
    if modelData ~= nil then
        heroStar = modelData.f_HeroQualityLimit;
    end
    if heroInfo.star < heroStar then
        return nil;
    end
    local modelId = heroInfo["partnerModelId"] or heroInfo["f_HeroID"] or 0;
    local items = {};
    for k, v in pairs(visitors) do
        local heroData = logicMgr.HeroManager.getHeroDatabyPartnerId(v, true);
        if heroData ~= nil then
            local attrCfg = this.getHeroManorData(modelId, heroData.star);
            if attrCfg ~= nil then
                local attr = decodeJsonStrToTabel(attrCfg.f_AttrAdd);
                for lk, lv in pairs(attr) do
                    local value = items[lv[1]] or 0;
                    value = value + lv[2];
                    items[lv[1]] = value;
                end
            end
        end
    end
    return items;
end

function HeroManorManager.setAttrItemInfo(obj, id, value)
    local attributeItemConfig = dataTable.getDataTableByStringId("t_attributelibrary", id);
    if attributeItemConfig.f_IsPanel ==1 then
        local intVal = Mathf.Round(value);
        local txtAttrName = obj:GetChild("name");
        local txtAttrValue = obj:GetChild("number");
        local imgAttr = obj:GetChild("image");

        txtAttrName.text = getLanguage(string.format(Config.LangAttribute,id));
        if attributeItemConfig.f_AttributeType==2 then
            txtAttrValue.text = (intVal/100).."%";
        else
            txtAttrValue.text =getNumString(intVal);
        end
        imgAttr.url = "ui://ICONAtlas/".."attr"..id;
    else
        obj.visible = false;
    end
end

function HeroManorManager.setHeadIcon(headIcon, modelId, icon)
    local skinId = logicMgr.SkinManager.getHeroSkinId(modelId);
    if skinId and tonumber(skinId) > 0 then
        HelperFunc.SetIcon(headIcon, logicMgr.SkinManager.GetHeroIconBySkinId1(skinId), EnumConst.ItemShowType.ICON);
    else
        HelperFunc.SetIcon(headIcon, icon, EnumConst.ItemShowType.ICON);
    end
end

function HeroManorManager.isAutoRed(cityId, index)
    local manorInfo = this.getManorInfo(cityId, index);
    local heroInfo = logicMgr.HeroManager.getHeroDatabyPartnerId(manorInfo.masterId, true);
    local heroStar = heroInfo.star;
    local lowStar = 150;
    local heroManorModel = dataTable.getDataTable("t_heromanormodel");
    local visitors = this.getManorVisitors(manorInfo.masterId) or {};
    for k, v in pairs(heroManorModel) do
        if heroStar >= v.f_MasterQuality then
            if visitors[v.f_Id] == nil then
                lowStar = 20;
                break;
            else
                local heroData = logicMgr.HeroManager.getHeroDatabyPartnerId(visitors[v.f_Id], true);
                if heroData.star < lowStar then
                    lowStar = heroData.star;
                end
            end
        end
    end
    local tableHeros = logicMgr.HeroManager.getOwnerHeroList();
    table.sort(tableHeros, logicMgr.HeroManager.sortHeroWithQuality);
    for i = 1, #tableHeros do
        local partnerId = tableHeros[i].partnerId;
        if not this.isManorMaster(partnerId) and not this.isManorGuest(partnerId) and tableHeros[i].star > lowStar and (this.isHighQuality() or tableHeros[i].star < 100) then
            return true;
        end
    end
    return false;
end

function HeroManorManager.isHighQuality()
    return this.highQuality;
end

function HeroManorManager.setHighQuality(value)
    local state = 0;
    if value then
        state = 1;
    end
    SetPlayerPrefs("ManorManager"..logicMgr.HeroManager.GetRoleInfo().playerId, state);
    this.highQuality = value;
end

return HeroManorManager